import React from 'react';
import {Button, Card, DatePicker, Form, Input, message, Popconfirm, Table, Tooltip, Pagination} from 'antd';
import SearchForm from '../../components/AutoForm/SearchForm';
import {connect} from "dva";
import moment from "moment";
import {OilSelect} from "../../components/Selection/OilSelect";
import EditForm from "../../components/AutoForm/EditForm";
import locale from "antd/es/date-picker/locale/zh_CN";

const { TextArea } = Input;

const EditableContext = React.createContext();

@connect(({car}) => ({
  requiredCols: car.requiredCols
}))
class EditableCell extends React.Component {


  getInput = (dataIndex, record) => {
    switch (dataIndex) {
      case 'kilometres':
        return <Input type="number"/>
      case 'drLicSendDate':
        return <DatePicker />
      case 'drLicRegDate':
        return <DatePicker />
      case 'annualDate':
        return <DatePicker />
      case 'insureTraffic':
        return <DatePicker />
      case 'insureThird':
        return <DatePicker />
      case 'scrapDate':
        return <DatePicker />
      case 'remark':
        return <TextArea rows={3} />;
      default:
        return <Input />
    }
  };

  renderCell = ({ getFieldDecorator }) => {
    const {
      editing,
      dataIndex,
      title,
      inputType,
      record,
      index,
      children,
      requiredCols,
      ...restProps
    } = this.props;
    return (
      <td {...restProps}>
        {editing ? (
          <Form.Item style={{ margin: 0, padding: 0}}>
            {getFieldDecorator(dataIndex, {
              rules: requiredCols[title],
              initialValue:
                dataIndex === 'drLicSendDate'
                || dataIndex === 'drLicRegDate'
                || dataIndex === 'annualDate'
                || dataIndex === 'scrapDate'
                || dataIndex === 'insureThird'
                || dataIndex === 'insureTraffic'
                ? record[dataIndex]
                  ? moment(record[dataIndex])
                  : ''
                : record[dataIndex],
            })(this.getInput(dataIndex, record))}
          </Form.Item>
        ) : (
          children
        )}
      </td>
    );
  };

  render() {
    return <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>;
  }
}

@connect(({car, loading}) => ({
  tableLoading: loading.effects['car/page'],
  oilLoading: loading.effects['car/oil'],
  insureLoading: loading.effects['car/insure'],
  tableData: car.pageList,
  pagination: car.pagination,
  columns: car.columns,
  searchFields: car.searchFields,
  searchValues: car.searchValues,
  editId: car.editId,
  selectionIds: car.selectionIds,
  selectedRows: car.selectedRows,
  columnsOil: car.columnsOil,
  columnsInsure: car.columnsInsure,
}))
class EditableTable extends React.Component {
  state = {
    insureTitle: '',
    oilForm: {},
    oilModal: false,
    oilRows: [
      {
        cols: [
          {
            label: '油卡编号',
            name: 'oilNo',
            md: 12,
            rules: [{ required: true, message: ' ' }],
            component: <OilSelect onSelect={(value) => {this.oilSelected(value)}}placeholder="请选择油卡" />,
          },
          {
            label: '车牌号',
            name: 'carNo',
            md: 12,
            component: <Input readOnly={true}/>
          }
        ],
      },{
        cols: [
          {
            label: '上次公里数',
            name: 'kilometresStart',
            md: 12,
            rules: [{ required: true, message: ' ' }],
            component: <Input type="number" readOnly={true}/>,
          },
          {
            label: '本次公里数',
            name: 'kilometresEnd',
            md: 12,
            component: <Input type="number"/>
          }
        ],
      },{
        cols: [
          {
            label: '加油升数',
            name: 'oilCount',
            md: 12,
            component: <Input type="number" />,
          },
          {
            label: '油价',
            name: 'oilPrice',
            md: 12,
            component: <Input type="number"/>
          }
        ],
      },{
        cols: [
          {
            label: '实际金额',
            name: 'oilOffAmount',
            md: 12,
            component: <Input type="number" />,
          },
          {
            label: '加油支付单号',
            name: 'oilPayNo',
            md: 12,
            component: <Input />
          }
        ],
      },{
        cols: [
          {
            label: '司机',
            name: 'driver',
            md: 12,
            rules: [{ required: true, message: ' ' }],
            component: <Input  />,
          },
        ],
      },{
        cols: [
          {
            label: '加油时间',
            name: 'oilTime',
            md: 12,
            rules: [{ required: true, message: ' ' }],
            component: <DatePicker locale={locale} showTime format="YYYY-MM-DD HH:mm:ss" placeholder="请输入加油时间" />,
          },
        ],
      }],
    insureForm: {},
    insureModal: false,
    insureRows: [
      {
        cols: [
          {
            label: '保险公司名称',
            name: 'comp',
            md: 12,
            rules: [{ required: true, message: ' ' }],
            component: <Input placeholder="请输入保险公司"/>,
          },
          {
            label: '保险单号',
            name: 'insureNo',
            md: 12,
            component: <Input placeholder="请输入保险单号"/>
          }
        ],
      },{
        cols: [
          {
            label: '保险生效时间',
            name: 'insureTimeStart',
            md: 12,
            rules: [{ required: true, message: ' ' }],
            component: <DatePicker showTime={true} format="YYYY-MM-DD HH:mm:ss"/>,
          },
          {
            label: '保险中止时间',
            name: 'insureTimeEnd',
            md: 12,
            rules: [{ required: true, message: ' ' }],
            component: <DatePicker showTime={true} format="YYYY-MM-DD HH:mm:ss"/>
          }
        ],
      },{
        cols: [
          {
            label: '保险类型',
            name: 'insureType',
            md: 12,
            component: <Input placeholder="请输入保险类型" />,
          },
          {
            label: '被保险人',
            name: 'insureName',
            md: 12,
            component: <Input placeholder="请输入被保险人"/>
          }
        ],
      },{
        cols: [
          {
            label: '保额',
            name: 'insureAmount',
            md: 12,
            component: <Input type="number" placeholder="请输入保额"/>,
          },
          {
            label: '保费',
            name: 'insureFee',
            md: 12,
            component: <Input type="number" placeholder="请输入保费" />
          }
        ],
      },{
        cols: [
          {
            label: '车牌号',
            name: 'carNo',
            md: 12,
            rules: [{ required: true, message: ' ' }],
            component: <Input  />,
          },
        ],
      }]
  };

  componentDidMount() {
    this.handleSearch();
  }
  cancel = () => {
    const { dispatch } = this.props;
    dispatch({
      type: 'car/handleEdit',
      payload: ''
    })
  };

  save(form, id) {
    const { dispatch } = this.props;
    form.validateFields((error, row) => {
      if (error) {
        return;
      }
      row.drLicSendDate = moment(row.drLicSendDate).add(8, 'h');
      row.drLicRegDate = moment(row.drLicRegDate).add(8, 'h');
      row.annualDate = moment(row.annualDate).add(8, 'h');
      row.insureTraffic = moment(row.insureTraffic).add(8, 'h');
      row.insureThird = moment(row.insureThird).add(8, 'h');
      row.scrapDate = moment(row.scrapDate).add(8, 'h');
      dispatch({
        type: 'car/save',
        payload: { ...row, id: id.id }
      }).then(() => {
        this.handleSearch()
      })
    });
  }

  handleEdit(key) {
    const { dispatch } = this.props;
    dispatch({
      type: 'car/handleEdit',
      payload: key
    })
  }

  handleSearchChange = (fields) => {
    const {dispatch} = this.props;
    dispatch({
      type: 'car/handleSearchChange',
      payload: fields
    })
  }

  handleAdd = () => {
    const { dispatch } = this.props;
    dispatch({
      type: 'car/handleAdd'
    })
  }

  handleSearch = (flag) => {
    const {dispatch, pagination, searchValues} = this.props;
    let pageParam = {pageSize: pagination.pageSize, current: flag==='btn' ? 1 : pagination.current}
    let searchParam = {};
    Object.keys(searchValues).map((key) => {
      if (key === 'annualDateStr' || key === 'scrapDateStr' || key === 'insureDateStr' || key === 'insureThirdStr' || key === 'insureTrafficStr') {
          const dateStr = searchValues[key].value
          searchParam[key] =dateStr ? dateStr.format('YYYY-MM-DD') : '';
      }else{
        searchParam[key] = searchValues[key]['value'];
      }
    })
    const param = {
      ...searchParam,
      ...pageParam
    };
    dispatch({
      type: 'car/page',
      payload: param
    })
  }

  onChange = (selectedRowKeys, selectedRows) => {
    const { dispatch } = this.props;
    dispatch({
      type: 'car/handleSelection',
      payload: {selectedRowKeys, selectedRows}
    })
  }

  onDel = () => {
    const { dispatch, selectionIds } = this.props;
    if(!selectionIds.length){
      return message.error('请选择一行要删除的数据')
    }
    dispatch({
      type: 'car/del',
      payload: selectionIds
    }).then(() => {
      this.handleSearch()
    })
  }
  onInsurance = () => {
    const { selectionIds, selectedRows } = this.props
    const { insureForm } = this.state
    if(selectionIds.length != 1){
      return message.error("请选择一辆车！")
    }
    this.setState({
      insureModal: true,
      insureForm: {
        ...insureForm,
        carNo: {
          name: "carNo",
          value: selectedRows[0].carNo
        }
      }
    })


  }
  onOil = () => {
    const { selectionIds, selectedRows } = this.props
    const { oilForm } = this.state
    if(selectionIds.length != 1){
      return message.error("请选择一辆车！")
    }
    this.setState({
      oilModal: true,
      oilForm: {
        ...oilForm,
        carNo: {
          name: "carNo",
          value: selectedRows[0].carNo
        },
        kilometresStart: {
          name: "kilometresStart",
          value: selectedRows[0].kilometres
        }
      }
    })

  }

  oilSelected = value => {
    const { oilForm } = this.state
    this.setState({
      oilForm: {
        ...oilForm,
        oilNo: {
          name: 'oilNo',
          value: value
        }
      }
    })
  }

  handleOilChange = fields => {
    const { oilForm } = this.state
    this.setState({
      oilForm: {
        ...oilForm,
        ...fields
      },
    });
  }

  handleInsureChange = fields => {
    const { insureForm } = this.state
    this.setState({
      insureForm: {
        ...insureForm,
        ...fields
      },
    });
  }
  handleOilVisible = () => {
    this.setState({
      oilModal: false
    })
  }
  handleInsureVisible = () => {
    this.setState({
      insureModal: false
    })
  }
  handleOilSub = (fields) => {
    const { dispatch } = this.props;
    const oilTime = this.state.oilForm.oilTime.value.add(8, 'h')
    dispatch({
      type: 'car/oil',
      payload: {
        ...fields,
        oilTime
      },
    }).then(() => {
      this.handleSearch();
      this.setState({ oilModal: false, oilForm: {} });
    });
  }

  handleInsureSub = (fields) => {
    const { dispatch } = this.props;
    dispatch({
      type: 'car/insure',
      payload: {
        ...fields,
      },
    }).then(() => {
      this.handleSearch();
      this.setState({ insureModal: false });
    });
  }

  expandedRowRender = record => {
    const { columnsOil, columnsInsure, searchValues } = this.props;
    const flag = searchValues['flag']['value'];
    let columns
    let dataSource
    if(flag === 'oil'){
      columns = columnsOil
      dataSource = record.oils
    }
    if(flag === 'insure'){
      columns = columnsInsure
      dataSource = record.insures
    }
    return <Table size="small" columns={columns} dataSource={dataSource} />;
  };

  render() {
    const {
      columns,
      pagination,
      tableLoading,
      oilLoading,
      tableData,
      searchFields,
      searchValues,
      insureLoading,
      editId,
      dispatch
    } = this.props;
    const components = {
      body: {
        cell: EditableCell,
      },
    };

    const optColumns = columns.map(col => {
      if (!col.editable) {
        return col;
      }
      return {
        ...col,
        onCell: record => ({
          record,
          inputType: 'text',
          dataIndex: col.dataIndex,
          title: col.title,
          editing: editId === record.id,
        }),
      };
    });
    optColumns.push({
      title: '操作',
      width: '120px',
      fixed: 'right',
      render: (text, record) => {
        const editable = editId === record.id;
        return editable ? (
          <span>
              <EditableContext.Consumer>
                {form => (
                  <Tooltip placement="bottom" title="保存">
                    <Button size="small"  onClick={() => this.save(form, record)} icon="save"></Button>
                  </Tooltip>
                )}
              </EditableContext.Consumer>
              <Popconfirm title="确认取消?" cancelText="取消" okText="确定" onConfirm={() => this.cancel(record.id)}>
                <Tooltip placement="bottom" title="撤回">
                  <Button size="small" icon="rollback"></Button>
                </Tooltip>
              </Popconfirm>
            </span>
        ) : (
          <Tooltip placement="bottom" title="编辑">
            <Button disabled={editId !== '' } size="small" icon="edit" onClick={() => this.handleEdit(record.id)}></Button>
          </Tooltip>
        );
      }
    })

    pagination.onChange = (page, pageSize) => {
      let searchParam = {};
      Object.keys(searchValues).map((key) => {
        searchParam[key] = searchValues[key]['value'];
      })
      dispatch({
        type: 'car/page',
        payload: {
          ...searchParam,
          current: page,
          pageSize
        }
      })
    }
    pagination.onShowSizeChange = (current, size) => {
      let searchParam = {};
      Object.keys(searchValues).map((key) => {
        searchParam[key] = searchValues[key]['value'];
      })
      dispatch({
        type: 'car/page',
        payload: {
          ...searchParam,
          current: current,
          pageSize: size
        }
      })
    }

    const rowSelection = {
      type: "checkbox",
      selections: this.props.selectedRows,
      selectedRowKeys: this.props.selectionIds,
      onChange: this.onChange
    };

    return (
      <Card bodyStyle={{padding: 0}}>
        <SearchForm
          header="车辆信息->操作"
          layout="inline"
          onFieldsChange={this.handleSearchChange}
          isAdd={true}
          isDel={true}
          isOil={true}
          /*isInsurance={true}*/
          onAdd={this.handleAdd}
          onSubmit={() => {this.handleSearch('btn')}}
          /*onInsurance={this.onInsurance}*/
          onOil={this.onOil}
          onDel={this.onDel}
          fields={searchFields}
          fieldValue={searchValues}
        />
        <EditableContext.Provider value={this.props.form}>
          <Table
            components={components}
            bordered
            rowKey="id"
            loading={tableLoading}
            dataSource={tableData}
            columns={optColumns}
            rowSelection={rowSelection}
            rowClassName="editable-row"
            scroll={{x: 'max-content'}}
            size="small"
            pagination={pagination}
            expandedRowRender={this.expandedRowRender}
          />
        </EditableContext.Provider>
        <EditForm
          title="加油"
          rows={this.state.oilRows}
          fieldValue={this.state.oilForm}
          onFieldsChange={this.handleOilChange}
          onCancel={this.handleOilVisible}
          confirmLoading={oilLoading}
          onOk={this.handleOilSub}
          visible={this.state.oilModal}
        />
        <EditForm
          title="车辆保险"
          rows={this.state.insureRows}
          fieldValue={this.state.insureForm}
          onFieldsChange={this.handleInsureChange}
          onCancel={this.handleInsureVisible}
          confirmLoading={insureLoading}
          onOk={this.handleInsureSub}
          visible={this.state.insureModal}
        />
      </Card>
    );
  }
}

const EditableFormTable = Form.create()(EditableTable);
export default EditableFormTable;
